<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

</body>

</html>
<script>
    //一.递归函数
    // 递归函数是在一个函数通过名字调用自身情况下构成的
    // 递归函数就函数内部调用函数本身


    //二.递归：
    //递:传递，递进.....。  
    //归:回来，基点.....。

    //案例：求阶乘
    //5!=5*4*3*2*1 = 5*4!
    //4!=4*3*2*1 = 4*3!
    //3!=3*2*4 = 3*2!
    //2!=2*1 = 2*1!
    //1!=1; -- 归


    //计算任意数的阶乘。
    // function jc(n) { //n=5
    //     return n * jc(n - 1); //Maximum call stack size exceeded栈溢出(内存有堆和栈组成)
    // }

    // console.log(jc(5));


    //解决：设置基点。
    // function jc(n) { //n=5
    //     if (n === 1) { //设置基点，归的值。
    //         return 1;
    //     }
    //     return n * jc(n - 1); //5*4!  4*3!  3*2!  2*1!  
    // }
    // console.log(jc(5)); //120


    //利用递归求斐波那契数列的前20项。（递归）
    //前面两项的和等于第三项。(F(n)=F(n - 1)+F(n - 2)（n ≥ 2，n ∈ N*）)
    //这个数列从第3项开始，每一项都等于前两项之和。
    //0,1,1,2,3,5,8,13,21......

    // function feibo(n) { //n:第几项，第20项。
    //     if (n === 1) { //设置基点，归的值。
    //         return 0;
    //     }
    //     if (n === 2) { //设置基点，归的值。
    //         return 1;
    //     }
    //     return feibo(n - 1) + feibo(n - 2);
    // }
    // console.log(feibo(20)); //4181


    //编写一个函数,输入n为偶数时,调用函数求1/2+1/4+1/6...+1/n,当输入n为奇数时,调用函数求 1+1/3+1/5...+1/n.
    function calc(n) {
        if (n === 1) {
            return 1;
        }
        if (n === 2) {
            return 1 / 2;
        }
        return calc(n - 2) + 1 / n;
    }

    // console.log(calc(6));
    // console.log(calc(5));
    // console.log(calc(4));
    // console.log(calc(3));

    //n = 6   1/2+1/4+1/6  => calc(4)+1/6  => calc(n-2)+1/n
    //n = 5   1+1/3+1/5 => clac(3)+1/5 => calc(n-2)+1/n
    //n = 4   1/2+1/4 =>  calc(2)+1/4  => calc(n-2)+1/n
    //n = 3   1+1/3  => calc(1)+1/3 => calc(n-2)+1/n

    //基点：calc(1)=>1   calc(2)=>1/2


    //利用递归求两个数字的最大公约数和最小公倍数(最小公倍数的算法，是两个数的乘积除以最大公约数)（递归）
    //最大公因数，也称最大公约数、最大公因子，指两个或多个整数共有约数中最大的一个
    //两个或多个整数公有的倍数叫做它们的公倍数
    // (12, 24) => 12;
    // (12, 24) => 24;

    function fn1(m, n) { //辗转相除法。
        var r = m % n;
        m = n;
        n = r;
        if (r === 0) {
            return m;
        } else {
            return fn1(m, n); //递归
        }
    }

    // console.log(fn1(12, 24));
    // console.log(fn1(3, 8)); //1

    //最小公倍数:和递归没有关系。是两个数的乘积除以最大公约数
    function fn2(m, n) {
        return (m * n) / fn1(m, n);
    }

    // console.log(fn2(12, 24)); //24

    console.log(fn2(3, 8)); //24
</script>